#include "mttgpumonitor.h"

MTTGpuMonitor::MTTGpuMonitor()
{
}

MTTGpuMonitor::~MTTGpuMonitor()
{
}

std::optional<double> MTTGpuMonitor::getGpuCoreUsage()
{
    // 使用查询命令获取GPU利用率信息，文档没给出输出示例，只能等实际测试，先预留
    auto result = executeMTCommand({"--query", "-i", "0", "-d", "UTILIZATION"});
    
    if (!result.has_value()) {
        return std::nullopt;
    }
    
    return parseUtilizationInfo(result.value());
}

std::optional<double> MTTGpuMonitor::getGpuMemUsage()
{
    // 使用查询命令获取内存信息，文档没给出输出示例
    auto result = executeMTCommand({"--query", "-i", "0", "-d", "MEMORY"});
    
    if (!result.has_value()) {
        return std::nullopt;
    }
    
    return parseMemoryUsageInfo(result.value());
}

std::optional<double> MTTGpuMonitor::getGpuCoreTemp()
{
    return -1;
}

std::optional<QString> MTTGpuMonitor::executeMTCommand(const QStringList& arguments)
{
    QProcess process;
    process.start("mthreads-gmi", arguments);
    process.waitForFinished(2000); // 2秒超时
    
    if (process.exitStatus() != QProcess::NormalExit || process.exitCode() != 0) {
        return std::nullopt;
    }
    
    return QString(process.readAllStandardOutput());
}

std::optional<double> MTTGpuMonitor::parseUtilizationInfo(const QString& utilizationOutput)
{
    // 不确定，猜测
    const QStringList possibleFields = {"GPU Utilization", "Utilization", "GPU Usage"};
    
    for (const QString& field : possibleFields) {
        // 使用正则表达式匹配字段值
        QRegularExpression regex(field + "\\s*[:]\\s*([\\d.]+)");
        QRegularExpressionMatch match = regex.match(utilizationOutput);
        
        if (match.hasMatch()) {
            bool ok = false;
            double usage = match.captured(1).toDouble(&ok);
            if (ok && usage >= 0.0 && usage <= 100.0 && !std::isnan(usage)) {
                return usage;
            }
        }
    }
    
    return std::nullopt;
}

std::optional<double> MTTGpuMonitor::parseMemoryUsageInfo(const QString& memoryOutput)
{
    // 不确定，猜测是这样
    QRegularExpression usedRegex("Memory Used\\s*[:]\\s*([\\d.]+)\\s*([MG]?B)");
    QRegularExpression totalRegex("Memory Total\\s*[:]\\s*([\\d.]+)\\s*([MG]?B)");
    
    QRegularExpressionMatch usedMatch = usedRegex.match(memoryOutput);
    QRegularExpressionMatch totalMatch = totalRegex.match(memoryOutput);
    
    if (usedMatch.hasMatch() && totalMatch.hasMatch()) {
        bool ok1 = false, ok2 = false;
        double used = usedMatch.captured(1).toDouble(&ok1);
        double total = totalMatch.captured(1).toDouble(&ok2);
        
        if (!ok1 || !ok2 || total <= 0.0 || std::isnan(used) || std::isnan(total)) {
            return std::nullopt;
        }
        
        // 处理单位转换（统一为MB）
        QString usedUnit = usedMatch.captured(2).toUpper();
        QString totalUnit = totalMatch.captured(2).toUpper();
        
        if (usedUnit == "GB" || usedUnit == "G") {
            used *= 1024;
        }
        
        if (totalUnit == "GB" || totalUnit == "G") {
            total *= 1024;
        } 
        double usage = (used / total) * 100.0;
        if (usage < 0.0 || usage > 100.0 || std::isnan(usage)) {
            return std::nullopt;
        }
        
        return usage;
    }
    
    return std::nullopt;
}